﻿using System;
using System.Collections.Generic;
using System.Text;
using Dare.Utilities.Data;
using System.Data.Common;
using MySql.Data.MySqlClient;
using Stone.Data;

namespace Stone.Data.MySql
{
    public class DataProviderManager : IDataProviderManager
    {
        Dictionary<Type, DataProviderBase> providers;
        private void SearchAllProviders()
        {
            providers = new Dictionary<Type, DataProviderBase>(50);

            Type[] types = this.GetType().Assembly.GetTypes();
            for (int i = 0; i < types.Length; i++)
            {
                if (!types[i].IsAbstract && typeof(DataProviderBase).IsAssignableFrom(types[i]))
                {
                    DataProviderBase obj = Activator.CreateInstance(types[i]) as DataProviderBase;
                    if (obj != null)
                    {
                        obj.DataProviderManager = this;
                        providers.Add(types[i].BaseType, obj);
                    }
                }
            }
        }

        public DataProviderManager()
        {
            SearchAllProviders();
        }

        public DataProviderManager(string connectionString)
        {
            this.defaultConnectionString = connectionString;
            SearchAllProviders();
        }

        #region IDataProviderManager 成员

        public IDataProviderManager CreateNew()
        {
            return new DataProviderManager();
        }

        public IDataProviderManager CreateNew(string connectionString)
        {
            return new DataProviderManager(connectionString);
        }

        public string Key
        {
            get { return "MySql"; }
        }

        public string Name
        {
            get { return "MySql 数据提供程序"; }
        }

        public string Description
        {
            get { return "采用官方 MySql 6.1 类库实现的　MySql 数据提供程序"; }
        }

        public DbProviderFactory DbProviderFactory
        {
            get
            {
                return global::MySql.Data.MySqlClient.MySqlClientFactory.Instance;
            }
        }

        public T GetDataProvider<T>() where T : DataProviderBase
        {
            if (providers.ContainsKey(typeof(T)))
            {
                return providers[typeof(T)] as T;
            }
            else
            {
                throw new NotImplementedException(Description + " 没有实现 " + typeof(T).Name + " 数据提供程序");
            }
        }

        public string BuildConnectionString(string server, int port, string dbName, string userName, string userPassword)
        {
            if (String.IsNullOrEmpty(server)) throw new ArgumentException("数据库服务器地址为空", server);
            MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder();
            builder.Server = server;
            if (port > 0 && port < 65536)
            {
                builder.Port = (uint)port;
            }
            builder.Database = dbName;
            builder.UserID = userName;
            builder.Password = userPassword;
            builder.CharacterSet = "utf8";
            builder.ConvertZeroDateTime = true;

            return builder.ToString();
        }

        private string defaultConnectionString;

        public string DefaultConnectionString
        {
            get
            {
                return defaultConnectionString;
            }
            set
            {
                defaultConnectionString = value;
            }
        }

        public void SetDefaultConnectionString(string server, int port, string dbName, string userName, string password)
        {
            defaultConnectionString = BuildConnectionString(server, port, dbName, userName, password);
        }

        public TransactionManager CreateTransaction()
        {
            return new TransactionManager(DefaultConnectionString, DbProviderFactory);
        }

        public TransactionManager CreateTransaction(string connectionString)
        {
            return new TransactionManager(connectionString, DbProviderFactory);
        }

        #endregion
    }
}
